package v.fingertext;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.EmbossMaskFilter;
import android.graphics.MaskFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Images;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;

public class FingerText extends Activity
        implements ColorPickerDialog.OnColorChangedListener {    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        //this is the line that sets the initial pen color
        mPaint.setColor(inkColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(2);
    }
    

    
    private Paint       mPaint;
    private Bitmap  	mBitmap;
    private boolean		inkChosen;
    private int bgColor = 0xFFFFFFFF;  //set initial bg color var to white
    private int inkColor =  0xFF000000; //set initial ink color var to black
    
    public void colorChanged(int color) {
    	//This is the implementation of the interface from colorpickerdialog.java
    	
     	if (inkChosen){
    		mPaint.setColor(color);
    		inkColor = color;
    	}
    	else {
    		mBitmap.eraseColor  (color);
    		bgColor = color;
    		//set the color to the user's last ink color choice
    		mPaint.setColor(inkColor); 
    	}
    		
    		
    	
    }

    public class MyView extends View {
        
    
        
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint   mBitmapPaint;
        
        public MyView(Context c) {
            super(c);
            
            mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
            
            //this sets the bg color for the bitmap
            mBitmap.eraseColor  (bgColor);
            mCanvas = new Canvas(mBitmap);
            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        }
        
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
        }
        
        @Override
        protected void onDraw(Canvas canvas) {
            //this is the line that changes the bg color in the initial canvas
        	canvas.drawColor(bgColor);
            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
            
            canvas.drawPath(mPath, mPaint);
        }
        
        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;
        
        private void touch_start(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }
        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;
            }
        }
        private void touch_up() {
            mPath.lineTo(mX, mY);
            // commit the path to our offscreen
            mCanvas.drawPath(mPath, mPaint);
            // kill this so we don't double draw
            mPath.reset();
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
            
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touch_start(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touch_move(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up();
                    invalidate();
                    break;
            }
            return true;
        }
    }
    
    private static final int BG_COLOR_ID = Menu.FIRST;
    private static final int INK_MENU_ID = Menu.FIRST + 1;
    private static final int CLEAR_MENU_ID = Menu.FIRST + 2;
    private static final int ERASER_MENU_ID = Menu.FIRST + 3;
    private static final int SEND_MENU_ID = Menu.FIRST + 4;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(0, BG_COLOR_ID, 0, "Background Color").setShortcut('3', 'b');
        menu.add(0, INK_MENU_ID, 0, "Ink Color").setShortcut('4', 'c');
        menu.add(0, CLEAR_MENU_ID, 0, "Clear All").setShortcut('5', 'e');
        menu.add(0, ERASER_MENU_ID, 0, "Eraser").setShortcut('6', 'x');
        menu.add(0, SEND_MENU_ID, 0, "Send").setShortcut('7', 's');

        /****   Is this the mechanism to extend with filter effects?
        Intent intent = new Intent(null, getIntent().getData());
        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
        menu.addIntentOptions(
                              Menu.ALTERNATIVE, 0,
                              new ComponentName(this, NotesList.class),
                              null, intent, 0, null);
        *****/
        return true;
    }
    
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        mPaint.setXfermode(null);
        mPaint.setAlpha(0xFF);

        switch (item.getItemId()) {
        
        	case BG_COLOR_ID:
        		new ColorPickerDialog(this, this, mPaint.getColor()).show();
        		inkChosen = false;
        		return true;
            case INK_MENU_ID:
                new ColorPickerDialog(this, this, mPaint.getColor()).show();
                //remember the user's last ink choice color so we can revert after eraser
                //to background color change -- otherwise ink is last bg color
                inkColor = mPaint.getColor();
                inkChosen = true;
                return true;
            case CLEAR_MENU_ID:
            	mBitmap.eraseColor  (bgColor);
                return true;
            case ERASER_MENU_ID:
            	//set pen color to bg color for 'erasing'
            	mPaint.setColor(bgColor);
                return true;
            case SEND_MENU_ID:
            		/* TODO need to decide whether to save image locally
            		 * and how to make it available if so. really only need to
            		 * save if we want to let users view later, or pick a
            		 * previous message to send again 
            		 */
            	
            		// this try-catch block creates a private file and an
            		// inputstream pointing to it for reading
            	FileInputStream ifs;
				try {
					FileOutputStream fs = openFileOutput("message_image", Context.MODE_PRIVATE);
					mBitmap.compress(CompressFormat.PNG, 100, fs);
					ifs = openFileInput("message_image");
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return true;
				}
					// inserts file pointed to by ifs into image gallery
				String url = Images.Media.insertImage(getContentResolver(),
	            			BitmapFactory.decodeStream(ifs),
	            			"Message image1", "Message image");
				
 					// alternative: inserts mBitmap into image gallery
/*            	String url = Images.Media.insertImage(getContentResolver(),
            			mBitmap, "Message image1", "Message image");
*/
					// creates the Intent to open the messaging app
					// with the image at url attached
            	Intent sendIntent = new Intent(Intent.ACTION_SEND); 
            	sendIntent.putExtra("sms_body", "Message created using FingerText"); 
            	sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
            	sendIntent.setType("image/png");
            	startActivity(sendIntent);
	            	/* TODO delete the image from the content provider
	            	 * following line deletes the image, but too soon!
	            	 */
//            	getContentResolver().delete(Uri.parse(url), null, null);
            	
            	//this resets canvas after send   
            	//could also reset to last user settings w/o var resets
            	bgColor = 0xFFFFFFFF;  //set bg color var back to white
                inkColor =  0xFF000000; //set ink color var back to black
                mBitmap.eraseColor  (bgColor);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
